package com.jt.www.util;


import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.util.EntityUtils;
import org.dom4j.DocumentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.UUID;

/**
 * HTTP请求相关工具类
 *
 * @author dongj
 */
public class HttpClientUtil {

    private final static Logger log = LoggerFactory.getLogger(HttpClientUtil.class);

//    private static CloseableHttpClient httpclient = null;

    static {
        // 初始化线程池
        RequestConfig params = RequestConfig.custom().setConnectTimeout(3000).setConnectionRequestTimeout(1000).setSocketTimeout(4000)
                .setExpectContinueEnabled(true).build();

        PoolingHttpClientConnectionManager pccm = new PoolingHttpClientConnectionManager();
        pccm.setMaxTotal(300); // 连接池最大并发连接数
        pccm.setDefaultMaxPerRoute(50); // 单路由最大并发数
//        httpclient = HttpClients.custom().setConnectionManager(pccm).setDefaultRequestConfig(params).setRetryHandler(retryHandler).build();
//        httpclient = HttpClients.custom().setConnectionManager(pccm).setDefaultRequestConfig(params).build();
    }

    /**
     * 发送 get请求
     */
    @SuppressWarnings("rawtypes")
    public static JSONObject doHttpGet(Map paramMap) throws URISyntaxException {
        StringBuffer sb = new StringBuffer();
        sb.append(paramMap.get("url"));

        if (paramMap.get("param") != null) {
            String param = paramMap.get("param").toString();

            sb.append("?");

            if (paramMap.get("isUrlEncoded") != null && Integer.parseInt(paramMap.get("isUrlEncoded").toString()) == 1) {
//				sb.append(parameterizeForGet(param));
            } else {
                sb.append(param);
            }
        }

        String strUrl = sb.toString();
//		"Content-Type: text/plain; charset=utf-8[\r][\n]"
//		Content-Type application/x-www-form-urlencoded
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            // 创建httpget.
            URL url = new URL(strUrl);
            URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null);
            HttpGet httpget = new HttpGet(uri);
            // 设置超时时间等
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(5000).setConnectionRequestTimeout(1000)
                    .setSocketTimeout(5000).build();
            httpget.setConfig(requestConfig);
            log.info("executing  request get:" + httpget.getURI());

//			httpget.setHeader("Content-Type", "application/x-www-form-urlencoded");

            // 执行get请求.
            CloseableHttpResponse response = httpclient.execute(httpget);
            try {
                // 获取响应实体
                HttpEntity entity = response.getEntity();
                log.info("--------------------------------------");
                log.info("响应状态:" + response.getStatusLine());
                if (entity != null) {

                    String entityString = EntityUtils.toString(entity, "UTF-8").trim();

                    log.info("响应内容:" + entityString);

                    if (entityString.contains("<?xml version"))//
                    {
                        try {
                            return Xml2jsonUtil.xml2Json(entityString);
                        } catch (DocumentException e) {
                            e.printStackTrace();
                        }
                    }

                    httpget.releaseConnection();

                    return JSONObject.parseObject(entityString);
                }
            } finally {
                response.close();
            }
        } catch (ParseException | IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭连接,释放资源
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    /**
     * 发送 post请求
     */
    @SuppressWarnings({"rawtypes"})
    public static Map doHttpPost(Map paramMap) {
        String url = paramMap.get("url").toString();
        String param = paramMap.get("param").toString();


        if (param == null) {
            return null;
        }

        CloseableHttpClient httpClient = HttpClients.createDefault();

        HttpPost httpPost = new HttpPost(url);
        log.info("executing  request post:" + httpPost.getURI());
        httpPost.setHeader("Content-Type", "application/json");
        try {
            StringEntity se = new StringEntity(param, Charset.forName("UTF-8"));
            se.setContentEncoding("UTF-8");
            // 发送Json格式的数据请求
            se.setContentType("application/json");
            httpPost.setEntity(se);

            CloseableHttpResponse response = httpClient.execute(httpPost);
            try {
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    log.info("--------------------------------------");
                    log.info("响应状态:" + response.getStatusLine());
                    String entityString = EntityUtils.toString(entity, "UTF-8");
                    log.info("响应内容:" + entityString);
                    Map<String, Object> resultMap = JSONObject.parseObject(entityString);
                    return resultMap;
                }
            } finally {
                response.close();
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭连接,释放资源
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    /**
     * 发送回调请求并返回回调响应
     *
     * @param url  回调url
     * @param json json格式报文字符串
     * @return 回调响应的报文字符串
     */
    public static String callPost(String url, String json) {
        URL u = null;
        HttpURLConnection con = null;
        String responseStr = "";
        UUID uuid = UUID.randomUUID();
        String tradeno = uuid.toString().replaceAll("-", "");
        // 尝试发送请求
        try {
            u = new URL(url);
            con = (HttpURLConnection) u.openConnection();
            con.setConnectTimeout(30000);
            con.setRequestMethod("POST");
            con.setDoOutput(true);
            con.setDoInput(true);
            con.setUseCaches(false);
            con.setRequestProperty("Content-Type", "application/json");
            OutputStreamWriter osw = new OutputStreamWriter(
                    con.getOutputStream(), "UTF-8");
            osw.write(json);
            osw.flush();
            osw.close();
        } catch (Exception e) {
            e.printStackTrace();
            return "{\"resp_head\":{\"radeno\":\"" + tradeno + "\",\"retcode\":\"0\",\"subcode\":\"9001\",\"message\":\"连接异常\"}}";
        } finally {
            if (con != null) {
                con.disconnect();
            }
        }
        // 读取相应内容
        StringBuffer buffer = new StringBuffer();
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    con.getInputStream(), "UTF-8"));
            String temp;
            while ((temp = br.readLine()) != null) {
                buffer.append(temp);
                buffer.append("\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "{\"resp_head\":{\"radeno\":\"" + tradeno + "\",\"retcode\":\"0\",\"subcode\":\"9002\",\"message\":\"读取内容异常\"}}";
        }
        if ((responseStr = buffer.toString()) != null) {
        }
        System.out.println(responseStr);
        return responseStr;
    }

    public static void main(String[] args) {
        String json =
                "{\"req_head\":{\"tradeno\":\"11111111111111111111111111111111\",\"password\":\"Server$guide_7.4\"},\"req_body\":{\"innerpolicyno\":\"11111\",\"policyno\":\"11111\",\"startdate\":\"2017-09-05\"," +
                        "\"enddate\":\"2017-09-05\",\"signdate\":\"2017-09-05\",\"agentcode\":\"123code\",\"inscompcode\":\"ins123456\"," +
                        "\"inscompname\":\"江泰保险公司\",\"inscompcode1\":\"ins123456\",\"inscompname1\":\"江泰保险公司2\",\"inscompcode2\":\"js123\"," +
                        "\"inscompname2\":\"江泰保险公司3\"," +
                        "\"appntcode\":\"js123\"," +
                        "\"appnttype\":\"1\"," +
                        "\"policyholder\":\"js123\"," +
                        "\"policyholder_idtype\":\"1\"," +
                        "\"policyholder_idno\":\"50039118792\"," +
                        "\"policyholder_sex\":\"1\",\"clientno\":\"js123\",\"contractno\":\"js123\",\"clientname\":\"js123\"," +
                        "\"projname\":\"js123\"," +
                        "\"channel\":\"01\"," +
                        "\"inputdate\":\"2017-09-05\"," +
                        "\"risklist\":[" +
                        "{" +
                        "\"riskcode\":\"001001\"," +
                        "\"amount\":\"14.5\"," +
                        "\"prem\":\"14.5\"," +
                        "\"mult\":\"12\"," +
                        "\"payageflag\":\"2\",\"payage\":\"1\",\"startdate\":\"2017-09-05\",\"enddate\":\"2017-09-05\",\"payway\":\"1\"}," +
                        "{" +
                        "\"riskcode\":\"001001\"," +
                        "\"amount\":\"12.5\"," +
                        "\"prem\":\"12.5\"," +
                        "\"mult\":\"12\"," +
                        "\"payageflag\":\"2\",\"payage\":\"1\",\"startdate\":\"2017-09-05\",\"enddate\":\"2017-09-05\",\"payway\":\"1\"}]," +
                        "\"insuredlist\":[" +
                        "{" +
                        "\"insuredno\":\"001001\"," +
                        "\"insuredname\":\"12.5\"," +
                        "\"insured_idtype\":\"1\"," +
                        "\"insured_idno\":\"12\"," +
                        "\"insured_sex\":\"2\",\"insured_birthdate\":\"2017-09-05\",\"relationcode\":\"44\"}," +
                        "{" +
                        "\"insuredno\":\"001001\"," +
                        "\"insuredname\":\"12.5\"," +
                        "\"insured_idtype\":\"1\"," +
                        "\"insured_idno\":\"12\"," +
                        "\"insured_sex\":\"2\",\"insured_birthdate\":\"2017-09-05\",\"relationcode\":\"44\"}]}}";
        callPost("http://10.10.32.105:8090/app/a/mhpolicy/fccont/getJsonData", json);
    }
}